﻿<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html>
<head>
    <title>Custom Infoboxes</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>

    <!-- Add a reference to the Bing Maps Control -->
    <script charset="UTF-8" type="text/javascript" src="http://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=7.0"></script>
    
    <!-- jQuery reference. Used to ensure cross browser support.  -->
    <script type="text/javascript" src="scripts/jquery.min.js"></script>

	<script type="text/javascript">
	    var map, customInfobox;

	    function GetMap() {
	        map = new Microsoft.Maps.Map(document.getElementById("myMap"), { credentials: "Your_Bing_Maps_Key" });

	        //Register and load the Custom Infobox Module
	        Microsoft.Maps.registerModule("CustomInfoboxModule", "scripts/minified/V7CustomInfobox.min.js");
	        Microsoft.Maps.loadModule("CustomInfoboxModule", { callback: function () {
	            //Create an instance of the custom infobox control and set intial options
	            customInfobox = new CustomInfobox(map, { orientation: 1, color: '#ccc', arrowWidth: 20 });
	        }
	        });

	        //Define custom properties for the pushpin, and polygon classes.
            //This is an example of one way to assign metadata to a shape.
	        Microsoft.Maps.Pushpin.prototype.title = null;
	        Microsoft.Maps.Pushpin.prototype.description = null;
	        Microsoft.Maps.Polygon.prototype.title = null;
	        Microsoft.Maps.Polygon.prototype.description = null;

	        /* Add some data to the map */

	        // Add a pin to the center of the map
	        var pin = new Microsoft.Maps.Pushpin(map.getCenter());

	        //Add some mock info about the pin
	        pin.title = "Pin 1";
	        pin.description = "This is the infobox for Pin 1.<br/><span style='color:red;'>Here is some custom HTML</span>";

	        //Add a handler for the pushpin click event.
	        Microsoft.Maps.Events.addHandler(pin, 'click', displayInfobox);

	        //Add the pushpin and info box to the map
	        map.entities.push(pin);

            //To demo the flexibility we will add a polygon too
	        var polygon = new Microsoft.Maps.Polygon([new Microsoft.Maps.Location(0, 20), new Microsoft.Maps.Location(45, 45), new Microsoft.Maps.Location(0, 60), new Microsoft.Maps.Location(30, 45), new Microsoft.Maps.Location(0, 20)]);

	        //Add some content for the infobox
	        polygon.title = "Test Polygon";
	        polygon.description = "<i>This is an infobox for the polygon.</i>";

	        //Add a handler for the polygon click event.
	        Microsoft.Maps.Events.addHandler(polygon, 'click', displayInfobox);

	        //Add the polygon to the map
	        map.entities.push(polygon);
	    }

	    /*
	    * Event handle method for when pushpin or polygon is clicked.
        */
	    function displayInfobox(e) {
	        switch (e.targetType){
	            case "pushpin":
                    //Offset infobox for pushpins
	                customInfobox.setOptions({ offset: { x: 0, y: 25} });

                    //Render infobox
                    renderInfobox(e.target.getLocation(), e.target.title, e.target.description);
	                break;
	            case "polygon":
	                //Don't offset the infobox for polygons
	                customInfobox.setOptions({ offset: { x: 0, y: 0} });

	                //calculate center of polygon
	                var anchor = calculatePolygonCentroid(e.target.getLocations());

	                //render infobox
	                renderInfobox(anchor, e.target.title, e.target.description);
	                break;
                default:
                    break;
            }
	    }

	    /*
	    * This method generates the content for the infobox then displays it. 
        * There are several ways to generate the content for your infobox, this is just one common scenario. 
        * In situations where you have a lot of pushpins/content consider using an AJAX approach and load content dynamically.
        */
	    function renderInfobox(latlong, title, description) {
	        if (customInfobox != null) {
	            //Define the layout contents in the infobox
	            var html = ["<div style='padding:10px'>"];

	            //Add title
	            html.push("<b>", title, "</b><br/>");

	            //Add discription
	            html.push(description, "<br/>");

	            //Add a custom button to zoom to location
	            html.push("<a href='javascript:void(0);' onclick='map.setView({zoom : 17, center:new Microsoft.Maps.Location(")
                html.push(latlong.latitude, ",", latlong.longitude, ")});'>Zoom to Location</a>");

	            html.push("</div>");

                //Render Infobox
	            customInfobox.show(latlong, html.join(''));
            }
	    }

        /*
        * Helper method for calculating a centroid of a polygon.
        * Based on the formulas here: http://rbrundritt.wordpress.com/2008/10/08/centroid-of-a-polygon/
        */
	    function calculatePolygonCentroid(latlongs) {
	        var p = map.tryLocationToPixel(latlongs, Microsoft.Maps.PixelReference.control);
	        var area = 0, x = 0, y = 0, temp;

	        if (latlongs.length > 0) {
	            
	            for (var i = 0; i < latlongs.length - 1; i++) {
	                temp = p[i].x * p[i + 1].y - p[i + 1].x * p[i].y;
	                area += temp;
	                x += (p[i].x + p[i + 1].x) * temp;
	                y += (p[i].y + p[i + 1].y) * temp;
	            }

	            area *= 0.5;

	            x /= (area * 6);
	            y /= (area * 6);
	        }

	        return map.tryPixelToLocation(new Microsoft.Maps.Point(x, y), Microsoft.Maps.PixelReference.control);
        }
    </script>
</head>
<body onload="GetMap();">
    <div id='myMap' style="position:relative; width:600px;height:500px;float:left;"></div>
    <div style="float:left;margin:5px;">
    Orientation <input type="button" onclick="customInfobox.setOptions({orientation:1});" value="Veritcal" />
                <input type="button" onclick="customInfobox.setOptions({orientation:0});" value="Horizontal" /><br />
    
    Color       <input type="button" onclick="customInfobox.setOptions({color:'#CCC'});" value="#CCC" />
                <input type="button" onclick="customInfobox.setOptions({color:'red'});" value="red" />
                <input type="button" onclick="customInfobox.setOptions({color:'#6ccdff'});" value="#6ccdff" />
                <input type="button" onclick="customInfobox.setOptions({color:'white'});" value="white" />
                <input type="button" onclick="customInfobox.setOptions({color:'transparent'});" value="transparent" /><br />

    Arrow Color <input type="button" onclick="customInfobox.setOptions({arrowColor:'#CCC'});" value="#CCC" />
                <input type="button" onclick="customInfobox.setOptions({arrowColor:'red'});" value="red" />
                <input type="button" onclick="customInfobox.setOptions({arrowColor:'#6ccdff'});" value="#6ccdff" />
                <input type="button" onclick="customInfobox.setOptions({arrowColor:'white'});" value="white" />
                <input type="button" onclick="customInfobox.setOptions({arrowColor:'transparent'});" value="transparent" /><br />

    Border Color <input type="button" onclick="customInfobox.setOptions({borderColor:'#CCC'});" value="#CCC" />
                <input type="button" onclick="customInfobox.setOptions({borderColor:'red'});" value="red" />
                <input type="button" onclick="customInfobox.setOptions({borderColor:'#6ccdff'});" value="#6ccdff" />
                <input type="button" onclick="customInfobox.setOptions({borderColor:'white'});" value="white" />
                <input type="button" onclick="customInfobox.setOptions({borderColor:'transparent'});" value="transparent" /><br />

    Arrow Width <input type="button" onclick="customInfobox.setOptions({arrowWidth:10});" value="10px" />
                <input type="button" onclick="customInfobox.setOptions({arrowWidth:20});" value="20px" />
                <input type="button" onclick="customInfobox.setOptions({arrowWidth:30});" value="30px" />
                <input type="button" onclick="customInfobox.setOptions({arrowWidth:40});" value="40px" /><br />

    Arrow Length <input type="button" onclick="customInfobox.setOptions({arrowLength:10});" value="10px" />
                <input type="button" onclick="customInfobox.setOptions({arrowLength:20});" value="20px" />
                <input type="button" onclick="customInfobox.setOptions({arrowLength:30});" value="30px" />
                <input type="button" onclick="customInfobox.setOptions({arrowLength:40});" value="40px" /><br />

    Offset      <input type="button" onclick="customInfobox.setOptions({offset:{x:0,y:0}});" value="(0,0)" />
                <input type="button" onclick="customInfobox.setOptions({offset:{x:0,y:25}});" value="(0,25)" />
                <input type="button" onclick="customInfobox.setOptions({offset:{x:25,y:25}});" value="(25,25)" /><br />

    Enable Tethering    <input type="button" onclick="customInfobox.setOptions({tether:true});" value="true" />
                        <input type="button" onclick="customInfobox.setOptions({tether:false});" value="false" />
                         *Move map around to test<br />

    Show Arrow      <input type="button" onclick="customInfobox.setOptions({showArrow:true});" value="true" />
                    <input type="button" onclick="customInfobox.setOptions({showArrow:false});" value="false" />
    </div>
</body>
</html>
